package com.luxsoft.siipap.em.replica.importadores.compras;

import java.sql.SQLException;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.Assert;

import com.luxsoft.siipap.model.core.Clase;
import com.luxsoft.siipap.model.core.Linea;
import com.luxsoft.siipap.model.core.Marca;
import com.luxsoft.siipap.model.core.Producto;
import com.luxsoft.siipap.model.core.Unidad;
import com.luxsoft.siipap.model.core.Producto.Presentacion;
import com.luxsoft.siipap.replica.aop.ExportadorManager;
import com.luxsoft.siipap.service.ServiceLocator2;
import com.luxsoft.siipap.util.DBUtils;

/**
 * Tarea especial para importar y/o actualizar productos de ARTICULO.DBF
 * 
 * NOTA: ES IMPORTANTE QUE ESTE PROCESO SE CORRA CON LA REPLICA NO HABILITADA
 * DESCONECTANDO LA UNIDAD DE RED EN LA QUE CAEN LOS ARCHIVOS
 * DE LO CONTRARIO LAS ALTAS BAJARAN AL DBF PROVOCANDO POSIBLES ERRORES 
 * 
 * @author ruben
 *
 */
public class ImportadorDeProductos2 {
	
	private static BasicDataSource ds;
	
	/**
	 * Crea el DataSoure para accesar a los DBF. Esto mediante un ODBC
	 * que existe en la PC con el nombre de SIIPAP
	 * @return
	 */
	public static DataSource getDataSource(){
		if(ds==null){
			ds=new BasicDataSource();
			ds.setDriverClassName("sun.jdbc.odbc.JdbcOdbcDriver");
			ds.setUrl("jdbc:odbc:SIIPAP");
		}
		return ds;
	}

	
	/**
	 * Termina la la conexion 
	 */
	public static void cloesDataSource(){
		try {
			if(ds!=null)
				ds.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * Esta es la parte importante del proces. 
	 * 
	 *  1 Lee todos los productos de MySQL
	 *  2 Procesa todos los articulos de ARTICULO.DBF
	 *    para cada registro realiza las siguientes operaciones
	 *    
	 *     2.1 Si este no existe en MySQL lo da de alta
	 *     2.2 si este ya existe copia las propiedades del Registro
	 *         y lo da de alta
	 *    
	 *  
	 */
	public void actualizaArticulos(){
		// Leemos todos los claves de producto  de MySQL
		String sql="SELECT CLAVE FROM SX_PRODUCTOS";
		List<String> clavesMySQL=ServiceLocator2.getJdbcTemplate().queryForList(sql, String.class);
		System.out.println("Claves de productos existentes en MySQL: "+clavesMySQL.size());
		
		// Leemos todos los registros del DBF
		JdbcTemplate template=new JdbcTemplate(getDataSource());
		List<Map<String, Object>> rows=template.queryForList("SELECT * FROM ARTICULO ORDER BY ARTCLAVE ASC");
		System.out.println("Registros del DBF:"+rows.size());
		ExportadorManager.enabled=false;
		//Procesamos cada articulo
		for(Map<String,Object> row:rows){
			try {
				Producto prod=getProductoFromDbfRow(row);
				if(clavesMySQL.contains(prod.getClave())){
					System.out.println("El producto "+prod.getClave()+" ya existe, actualizando sus propiedades");
					
					Producto existente=ServiceLocator2.getProductoManager().buscarPorClave(prod.getClave());
					
					
					/*existente.setActivo(prod.isActivo());
					existente.setActivoCompras(prod.isActivoCompras());
					existente.setActivoComprasObs(prod.getActivoComprasObs());
					existente.setActivoInventario(prod.isActivoInventario());
					existente.setActivoInventarioObs(prod.getActivoInventarioObs());
					existente.setActivoVentas(prod.isActivoVentas());
					existente.setActivoVentasObs(prod.getActivoVentasObs());
					existente.setDescripcion(prod.getDescripcion());
					existente.setKilos(prod.getKilos());
					existente.setGramos(prod.getGramos());
					existente.setLineaOrigen(prod.getLineaOrigen());
					existente.setModoDeVenta(prod.getModoDeVenta());
					existente.setPrecioContado(prod.getPrecioContado());
					existente.setPrecioCredito(prod.getPrecioCredito());
					existente.setDeLinea(prod.isDeLinea());
					existente.setUnidad(prod.getUnidad());
					*/
					
					/*
					if(existente.getModoDeVenta()==null){
						existente.setModoDeVenta(prod.getModoDeVenta());
					}
					*/
					
					//existente.setModoDeVenta(prod.getModoDeVenta());
					existente.setPrecioContado(prod.getPrecioContado());
					existente.setPrecioCredito(prod.getPrecioCredito());
					//DBUtils.whereWeAre();
					
					
					existente=ServiceLocator2.getProductoManager().save(existente);
					//System.out.println("Modo de venta: "+existente.getModoDeVenta());
					
					System.out.println("Producto actualizado: "+existente);
					
				}else{					
					//prod=(Producto)ServiceLocator2.getProductoManager().save(prod);
					//System.out.println("Producto generado: "+prod);
				}
			} catch (Exception e) {
				//System.out.println("Error procesando el registro: "+row);
				e.printStackTrace();
			}			
		}
		ExportadorManager.enabled=true;
		
	}
	
	private Clase claseGenerica;
	
	private Clase getClase(){
		if(claseGenerica==null){
			claseGenerica=(Clase)ServiceLocator2.getUniversalDao().get(Clase.class, 99l);
		}
		return claseGenerica;
	}
	
	private Linea lineaGenerica;
	
	private Linea getLinea(){
		if(lineaGenerica==null){
			lineaGenerica=(Linea)ServiceLocator2.getUniversalDao().get(Linea.class, 119l);
		}
		return lineaGenerica;
	}
	
	private Marca marcaGenerica;
	
	private Marca getMarca(){
		if(marcaGenerica==null){
			marcaGenerica=(Marca)ServiceLocator2.getUniversalDao().get(Marca.class, 119l);
		}
		return marcaGenerica;
	}
	
	private Set<Unidad> unidades;
	
	private Unidad getUnidad(String s){
		if(unidades==null){
			unidades=new HashSet<Unidad>();
			unidades.addAll(ServiceLocator2.getUniversalDao().getAll(Unidad.class));
		}
		for(Unidad u:unidades){
			if(u.getUnidad().equals(s.trim())){
				return u;
			}
		}
		Assert.isTrue(false,"No localizo la unidad: "+s);
		return null;
	}
	
	/**
	 * Este es el metodo que mapea un registro del DBF a un bean Producto
	 * 
	 * @param row
	 * @return
	 */
	private Producto getProductoFromDbfRow(Map<String, Object> row){
		Producto p=new Producto();
		//Obtenemos todas las propiedades del Articulo
		String ARTCLAVE=(String)row.get("ARTCLAVE");
		String ARTNOMBR=(String)row.get("ARTNOMBR");
		Number ARTKILOS=(Number)row.get("ARTKILOS");
		Number ARTGRAMS=(Number)row.get("ARTGRAMS");
		Number ARTPRECI=(Number)row.get("ARTPRECI");
		Number ARTPRECRE=(Number)row.get("ARTPRECRE");
		Number ARTPRENU=(Number)row.get("ARTPRENU");
		Number ARTPRENU2=(Number)row.get("ARTPRENU2");
		String ARTFACNETO=(String)row.get("ARTFACNETO");
		String ARTUNIDAD=(String)row.get("ARTUNIDAD");		
		Number ARTCOSTO=(Number)row.get("ARTCOSTO");
		String ARTCODORIG=(String)row.get("ARTCODORIG");
		Date ARTFECORI=(Date)row.get("ARTFECORI");		
		String ARTFAMILIA=(String)row.get("ARTFAMILIA");
		String ARTOBSER=(String)row.get("ARTOBSER");
		Date ARTFECAL=(Date)row.get("ARTFECAL");
		Date ARTFEBAJ=(Date)row.get("ARTFEBAJ");
		String ARTESTADO=(String)row.get("ARTESTADO");		
		String ARTOPEVECO=(String)row.get("ARTOPEVECO");
		String ARTOPEINV=(String)row.get("ARTOPEINV");
		String ARTOPEINCO=(String)row.get("ARTOPEINCO");		
		Date ARTFESUS=(Date)row.get("ARTFESUS");
		String ARTCOMSUS=(String)row.get("ARTCOMSUS");
		String ARTDESPHP=(String)row.get("ARTDESPHP");
		String ARTAFEINV=(String)row.get("ARTAFEINV");		 
		Number ARTUCOST=(Number)row.get("ARTUCOST");		
		Number ARTCOSPO=(Number)row.get("ARTCOSPO");
		String ARTOPEVEN=(String)row.get("ARTOPEVEN");
		String ARTUSUAR=(String)row.get("ARTUSUAR");
		String ARTOPECOM=(String)row.get("ARTOPECOM");
		String ARTOPECOCO=(String)row.get("ARTOPECOCO");
		Number ARTPRECI_B=(Number)row.get("ARTPRECI_B");
		Number ARTPRECREB=(Number)row.get("ARTPRECREB");
		Number ARTPRENU_B=(Number)row.get("ARTPRENU_B");
		Number ARTPRENU2B=(Number)row.get("ARTPRENU2B");
		Number ARTPRECI_C=(Number)row.get("ARTPRECI_C");
		Number ARTPRECREC=(Number)row.get("ARTPRECREC");
		Number ARTPRENU_C=(Number)row.get("ARTPRENU_C");
		Number ARTPRENU2C=(Number)row.get("ARTPRENU2C");
		Number ARTPRECI_D=(Number)row.get("ARTPRECI_D");
		Number ARTPRECRED=(Number)row.get("ARTPRECRED");
		Number ARTPRENU_D=(Number)row.get("ARTPRENU_D");
		Number ARTPRENU2D=(Number)row.get("ARTPRENU2D");
		Number ARTFACTMIN=(Number)row.get("ARTFACTMIN");
		String ARTCLASIFI=(String)row.get("ARTCLASIFI");
		
		p.setClave(ARTCLAVE.trim());		
		p.setActivo(ARTESTADO.trim().equalsIgnoreCase("A")?Boolean.TRUE:Boolean.FALSE);		
		//p.setAcabado(acabado); NO ENCONTRO
		p.setActivoCompras(ARTOPECOM.trim().equalsIgnoreCase("S")?Boolean.TRUE:Boolean.FALSE);
		p.setActivoComprasObs(ARTOPECOCO);
		p.setActivoInventario(ARTAFEINV.trim().equalsIgnoreCase("S")?Boolean.TRUE:Boolean.FALSE);
		p.setActivoInventarioObs(ARTOPEINCO);
		p.setActivoVentas(ARTOPEVEN.trim().equalsIgnoreCase("S")?Boolean.TRUE:Boolean.FALSE);
		p.setActivoVentasObs(ARTOPEVECO);	
		p.setDeLinea(ARTCLASIFI.trim().equalsIgnoreCase("L")?Boolean.TRUE:Boolean.FALSE);
		//p.setAncho(ancho);
		//p.setCalibre(calibre);
		//p.setCaras(caras);		
		p.setClase(getClase());
		//p.setColor(color);
		//p.setDeLinea(deLinea);
		p.setDescripcion(ARTNOMBR.trim());
		p.setGramos(ARTGRAMS.intValue());
		p.setInventariable(p.isActivoInventario());
		p.setKilos(ARTKILOS.doubleValue());
		//p.setLargo(largo);
		p.setLinea(getLinea());
		p.setLineaOrigen(ARTFAMILIA.trim());
		p.setMarca(getMarca());
		p.setModoDeVenta(ARTFACNETO.trim());
		//p.setNacional(nacional);
		p.setServicio(false);
		p.setUnidad(getUnidad(ARTUNIDAD));
		p.setPrecioContado(ARTPRECI.doubleValue());
		p.setPrecioCredito(ARTPRECRE.doubleValue());
		p.setPresentacion(Presentacion.EXTENDIDO);			
		return p;
	}
	
	public static void main(String[] args) {		
		DBUtils.whereWeAre();
		try {
			
			ImportadorDeProductos2 imp=new ImportadorDeProductos2();
			imp.actualizaArticulos();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			ImportadorDeProductos2.cloesDataSource();
		}
		
	}


}
